
#include <BLight>
#include <BCamera>
#include <BImage>
#include <BMaterial>
#include <BSurface>
#include <BGeometry>
#include <BState>
#include <BRender>
#include <BMesh>
#include <BStrollControl>
#include <BSphereControl>
#include <BScene>
#include <BReadWrite>
#include <BGridLayout>
#include <BVBoxLayout>
#include <BViewer>
#include <BSlider>
#include <BMainWindow>
#include <BApplication>

using namespace BWE;

class AxisNode : public BNode
{
public:
	AxisNode()
	{

	}
	~AxisNode()
	{

	}

	void connects(BSlider* yawSlider, BSlider* pitchSlider)
	{
		connect(yawSlider, Signal_ValueChanged, &AxisNode::procYawChanged);
		connect(pitchSlider, Signal_ValueChanged, &AxisNode::procPitchChanged);
	}

	virtual void render(BRender& render)
	{
		render.setLighting(false);
		render.setLineWidth(3);

		render.setColor(1, 0, 0);
		render.drawLine(0, 0, 0, 10, 0, 0);

		render.setColor(0, 1, 0);
		render.drawLine(0, 0, 0, 0, 10, 0);

		render.setColor(0, 0, 1);
		render.drawLine(0, 0, 0, 0, 0, 10);

		BQuater xrotate(euler.x(), BVector(1, 0, 0));
		BQuater yrotate(euler.y(), BVector(0, 1, 0));
		BQuater zrotate(euler.z(), BVector(0, 0, 1));
		BVector point(10, 0, 0);
		BMatrix matrix;
		matrix.setRotate(xrotate * yrotate * zrotate);
		point *= matrix;
		render.setColor(1, 1, 1);
		render.drawLine(BVector(), point);
	}

	void procYawChanged(BObject* object, const BValue& value)
	{
		int yaw = value;
		euler.y() = (yaw / 100.0f * PI2);
	}
	void procPitchChanged(BObject* object, const BValue& value)
	{
		int pitch = value;
		euler.x() = (pitch / 100.0f * PI2);
	}
private:
	BVector	euler;
};

BGeometry* createTerrain(BImage* image)
{
	if (image)
	{
		BSize size = image->size();
		int count = size.width() * size.height();
		BSurface* surface = new BSurface(size.width(), size.height(), size.width() - 1, size.height() - 1);
		BVectorArray* vertices = surface->vertices();
		unsigned short* data = (unsigned short*)image->pixels()->data();
		for (int r = 0; r < size.height(); r++)
		{
			int head = r * size.width();
			for (int c = 0; c < size.width(); c++)
			{
				int pos = head + c;
				vertices->set(pos, BVector(c, r, data[pos] / 100.0f));
			}
		}
		surface->smooth();


		return surface;
	}
	return 0;
}

int main(int argc, char** argv)
{
	BApplication app(argc, argv);
	app.addPluginPath("E:/BWE/build/bin/plugin");

	BImage* image = Read<BImage>("E:/Export17-07-02.tiff");
	BGeometry* terrain = createTerrain(image);
	if (!terrain)
		return 0;
	terrain->setColor(255, 255, 255);
	//BImage* texureImgae = Read<BImage>("E:/earth/image1/Export21-11-33.tiff");
	//terrain->setTexture(image);

	BMaterial* material = new BMaterial();
	terrain->setMaterial(material);

	BState* state = new BState();
	state->setLighting(true);
	state->setCullBack(false);

	BNode* node = new BNode();
	node->setState(state);
	node->addShape(terrain);

	BSceneHolder scene = new BScene();
	scene->addNode(node);

	AxisNode* axis = new AxisNode();
	scene->addNode(axis);

	BLight* light = new BLight();
	light->setAmbient(36, 36, 36);
	light->setDiffuse(200, 200, 200);
	light->setSpecular(200, 200, 200);
	light->setPosition(60, -60, 60);
	scene->addNode(light);

	BCameraHolder camera = new BCamera();
	camera->setPosition(-30, -30, 30);
	camera->setCenter(0, 0, 0);
	BSphereControl* control = new BSphereControl();

	BViewer* viewer = new BViewer();
	{
		viewer->setScene(scene);
		viewer->setCamera(camera);
		viewer->setControl(control);
		viewer->show();

		BSlider* yawSlider = new BSlider();
		BSlider* pitchSlider = new BSlider();
		axis->connects(yawSlider, pitchSlider);

		BVBoxLayout* vlayout = new BVBoxLayout();
		vlayout->addWidget(yawSlider);
		vlayout->addWidget(pitchSlider);
		vlayout->setRect(BRect(10, 10, 200, 36));

		viewer->setLayout(vlayout, Part_None);
	}

	BMainWindow* mw = new BMainWindow();
	mw->setTitle("main window");
	mw->setMargins(10);
	mw->show();

	BVBoxLayout* layout = new BVBoxLayout(mw);
	layout->addWidget(viewer);

	return app.execute();
}